package com.sotnyk.sspeed.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.sotnyk.sspeed.R;

public class SsAppState {
    private static SsAppState sSsAppState;

    private static final String TAG = "SsAppState";
    private static final String SELECTED_LIMIT_NAME = "SELECTED_LIMIT";
    private static final String LIMIT_NAME = "SPEED_LIMIT";

    private static final int MAX_LIMIT_NUMBER = 1;

    private float mWarningLimit = 0.95f; // 95%
    private int mSelectedLimit = -1;
    private final int[] mSpeedLimits = new int[MAX_LIMIT_NUMBER + 1];
    private SpeedUnits mCurrentSpeedUnits = SpeedUnits.KILOMETERS_PER_HOUR;
    private boolean mDarkThemeUsed = false;

    private final SharedPreferences mPrefs;
    private final Context mAppContext;

    private SsAppState(Context appContext) {
        mSpeedLimits[0] = 60;
        mSpeedLimits[1] = 90;
        this.mAppContext = appContext;
        mPrefs = PreferenceManager.getDefaultSharedPreferences(appContext);
        tryToLoadState();
    }

    private void tryToLoadState() {
        setSelectedLimit(mPrefs.getInt(SELECTED_LIMIT_NAME, -1));
        for (int i = 0; i <= MAX_LIMIT_NUMBER; ++i) {
            setSpeedLimits(i, mPrefs.getInt(LIMIT_NAME + i, getSpeedLimits(i)));
        }

        String speedUnits = mPrefs.getString(
                mAppContext.getString(R.string.pr_speed_units_key), "0");
        if (speedUnits.equalsIgnoreCase("1")) {
            mCurrentSpeedUnits = SpeedUnits.MILES_PER_HOUR;
        } else if (speedUnits.equalsIgnoreCase("2")) {
            mCurrentSpeedUnits = SpeedUnits.METERS_PER_SECOND;
        } else {
            mCurrentSpeedUnits = SpeedUnits.KILOMETERS_PER_HOUR;
        }

        mDarkThemeUsed = mPrefs.getBoolean(mAppContext.getString(R.string.pr_dark_theme_used_key),
                false);

        mWarningLimit = safeParseFloat(mPrefs.getString(mAppContext.getString(R.string.pr_speed_warning_limit_key),
                "" + mWarningLimit), mWarningLimit);
    }

    private static float safeParseFloat(String strValue, float defValue) {
        float result = defValue;
        try {
            result = Float.parseFloat(strValue);
        } catch (NumberFormatException e) {
            Log.w(TAG, "Cannot convert to float: " + strValue);
        }
        return result;
    }

    public void saveState() {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putInt(SELECTED_LIMIT_NAME, getSelectedLimit());
        for (int i = 0; i <= MAX_LIMIT_NUMBER; ++i) {
            editor.putInt(LIMIT_NAME + i, getSpeedLimits(i));
        }
        editor.putString(mAppContext.getString(R.string.pr_speed_units_key), ""
                + mCurrentSpeedUnits.ordinal());
        editor.putBoolean(mAppContext.getString(R.string.pr_dark_theme_used_key), mDarkThemeUsed);
        editor.apply();
    }

    public void refreshState() {
        tryToLoadState();
    }

    public static SsAppState get(Context context) {
        if (sSsAppState == null) {
            sSsAppState = new SsAppState(context.getApplicationContext());
        }
        return sSsAppState;
    }

    public int getSelectedLimit() {
        return mSelectedLimit;
    }

    public void setSelectedLimit(int selectedLimit) {
        if (selectedLimit < -1 || selectedLimit > MAX_LIMIT_NUMBER)
            mSelectedLimit = -1;
        else
            mSelectedLimit = selectedLimit;
    }

    public int getSpeedLimits(int index) {
        return mSpeedLimits[index];
    }

    public void setSpeedLimits(int index, int speedLimit) {
        mSpeedLimits[index] = speedLimit;
    }

    public SpeedUnits getCurrentSpeedUnits() {
        return mCurrentSpeedUnits;
    }

    public String getAlarmSound() {
        return mPrefs.getString(
                mAppContext.getString(R.string.pr_alarm_ringtone_key),
                "");
    }

    public Boolean isUseSpeech() {
        return mPrefs.getBoolean(mAppContext.getString(R.string.pr_use_speech_key), true);
    }

    public Boolean isSaySatellitesState() {
        return mPrefs.getBoolean(mAppContext.getString(R.string.pr_say_satellites_state_key), true);
    }

    public Boolean getDarkThemeUsed() {
        return mDarkThemeUsed;
    }

    public void setDarkThemeUsed(boolean darkThemeUsed) {
        mDarkThemeUsed = darkThemeUsed;
    }

    public float getWarningLimit() {
        return mWarningLimit;
    }

}
